package cn.openea.perpartner.meily.eventlistener.listener;

import cn.hutool.core.date.LocalDateTimeUtil;
import cn.openea.perpartner.common.core.constant.DateConstant;
import cn.openea.perpartner.common.core.utils.DateUtils;
import cn.openea.perpartner.common.core.utils.StringUtils;
import cn.openea.perpartner.meily.constant.enums.ExpressCompany;
import cn.openea.perpartner.meily.constant.enums.LogisticsModule;
import cn.openea.perpartner.meily.eventlistener.event.SyncLogisticsEvent;
import cn.openea.perpartner.meily.thirdparty.ExpressServiceApi;
import cn.openea.perpartner.meily.web.entity.GroupBuyingSub;
import cn.openea.perpartner.meily.web.entity.LogisticsInfo;
import cn.openea.perpartner.meily.web.entity.ProvideSamplesSub;
import cn.openea.perpartner.meily.web.entity.dto.GroupBuyingSubDTOFactory;
import cn.openea.perpartner.meily.web.entity.dto.LogisticsDTOFactory.LogisticsRealTimeDTO;
import cn.openea.perpartner.meily.web.entity.dto.TrialEvaluationSubDTO;
import cn.openea.perpartner.meily.web.service.ILogisticsInfoService;
import cn.openea.perpartner.meily.web.service.logistics.businessModule.LogisticsModlueHandler;
import cn.openea.perpartner.meily.web.service.logistics.businessModule.LogisticsModuleService;
import com.alibaba.fastjson.JSONObject;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;

/**
 * @author ysk
 * @version 1.0.1
 * @Description 同步物流监听器
 * @createTime 2023年05月10日 18:19:00
 */
@Component
public class SyncLogisticsEventListener {

    @Resource
    private GroupBuyingSubDTOFactory groupBuyingSubDTOFactory;
    @Resource
    private ILogisticsInfoService logisticsInfoService;
    @Resource
    private ExpressServiceApi expressServiceApi;
    @Resource
    private LogisticsModlueHandler logisticsModlueHandler;

    @EventListener
    public void groupBuyOrderSync(SyncLogisticsEvent syncLogisticsEvent) {
        Object object = syncLogisticsEvent.getObject();
        LogisticsRealTimeDTO realTimeDTO = syncLogisticsEvent.getRealTimeDTO();
        String logisticsId = syncLogisticsEvent.getLogisticsId();
        if (!(object instanceof GroupBuyingSub)) {
            return;
        }
        GroupBuyingSub groupBuyingSub = (GroupBuyingSub) object;
        GroupBuyingSubDTOFactory.DetailsDto detailsDto = groupBuyingSubDTOFactory
                .toDetailsDto.apply(groupBuyingSub);
        if (StringUtils.isBlank(detailsDto.getDeliveryTime())) {
            detailsDto.setDeliveryTime(DateUtils.getNow());
        }
        logisticsInfoService.saveOrUpdate(LogisticsInfo.builder()
                .id(StringUtils.isNotBlank(logisticsId) ? logisticsId : null)
                .moduleId(detailsDto.getId())
                .module(LogisticsModule.GROUPBUY.getModuleCode())
                .userId(detailsDto.getPartnerId())
                .goodsName(detailsDto.getGoodsName())
                .tradingTime(LocalDateTimeUtil.parse(detailsDto.getJoinTime(), DateConstant.DEFAULT_DATE_TIME_PATTERN))
                .deliveryTime(LocalDateTimeUtil.parse(detailsDto.getDeliveryTime(), DateConstant.DEFAULT_DATE_TIME_PATTERN))
                .tradingId(detailsDto.getOrderId())
                .phone(detailsDto.getConsigneePhoneNum())
                .courierNumber(detailsDto.getCourierNumber())
                .expressCompany(realTimeDTO.getCom())
                .consigneeAddress(detailsDto.getConsigneeAddress())
                .consigneeName(detailsDto.getConsigneeName())
                .dynamicContext(realTimeDTO.getLogisticsDynamicList() == null ? null : JSONObject.toJSONString(realTimeDTO.getLogisticsDynamicList()))
                .status(realTimeDTO.getState())
                .businessStatus("已完成".equals(detailsDto.getOrderStatus()) ? (short) 1 : (short) 0)
                .build());
    }

    @EventListener
    public void samplesSync(SyncLogisticsEvent syncLogisticsEvent) {
        Object object = syncLogisticsEvent.getObject();
        LogisticsRealTimeDTO realTimeDTO = syncLogisticsEvent.getRealTimeDTO();
        String logisticsId = syncLogisticsEvent.getLogisticsId();
        if (!(object instanceof ProvideSamplesSub)) {
            return;
        }
        ProvideSamplesSub samplesSub = (ProvideSamplesSub) object;
        if (StringUtils.isBlank(samplesSub.getDeliveryGoodsTime())) {
            samplesSub.setDeliveryGoodsTime(DateUtils.getNow());
        }
        logisticsInfoService.saveOrUpdate(LogisticsInfo.builder()
                .id(StringUtils.isNotBlank(logisticsId) ? logisticsId : null)
                .moduleId(samplesSub.getId())
                .module(LogisticsModule.SAMPLES.getModuleCode())
                .tradingId(samplesSub.getOrderId())
                .userId(samplesSub.getPartnerId())
                .goodsName(samplesSub.getGoodsName())
                .tradingTime(LocalDateTimeUtil.parse(samplesSub.getCreateTime(), DateConstant.DEFAULT_DATE_TIME_PATTERN))
                .deliveryTime(LocalDateTimeUtil.parse(samplesSub.getDeliveryGoodsTime(), DateConstant.DEFAULT_DATE_TIME_PATTERN))
                .phone(samplesSub.getConsigneePhoneNum())
                .courierNumber(samplesSub.getCourierNumber())
                .expressCompany(realTimeDTO.getCom())
                .consigneeAddress(samplesSub.getConsigneeAddress())
                .consigneeName(samplesSub.getConsigneeName())
                .dynamicContext(realTimeDTO.getLogisticsDynamicList() == null ? null : JSONObject.toJSONString(realTimeDTO.getLogisticsDynamicList()))
                .status(realTimeDTO.getState())
                .businessStatus("已完成".equals(samplesSub.getOrderStatus()) ? (short) 1 : (short) 0)
                .build());
    }


    @EventListener
    public void evaluationSync(SyncLogisticsEvent syncLogisticsEvent) {
        Object object = syncLogisticsEvent.getObject();
        LogisticsRealTimeDTO realTimeDTO = syncLogisticsEvent.getRealTimeDTO();
        String logisticsId = syncLogisticsEvent.getLogisticsId();
        if (!(object instanceof TrialEvaluationSubDTO)) {
            return;
        }
        TrialEvaluationSubDTO evaluationSubDTO = (TrialEvaluationSubDTO) object;
        if (StringUtils.isBlank(evaluationSubDTO.getDeliveryGoodsTime())) {
            evaluationSubDTO.setDeliveryGoodsTime(DateUtils.getNow());
        }
        logisticsInfoService.saveOrUpdate(LogisticsInfo.builder()
                .id(StringUtils.isNotBlank(logisticsId) ? logisticsId : null)
                .moduleId(evaluationSubDTO.getDocUnid())
                .module(LogisticsModule.EVALUATION.getModuleCode())
                .tradingId(evaluationSubDTO.getTaskNumber())
                .goodsName(evaluationSubDTO.getSubject())
                .userId(evaluationSubDTO.getPartnerId())
                .tradingTime(LocalDateTimeUtil.parse(evaluationSubDTO.getDocCreatedTime(), DateConstant.DEFAULT_DATE_TIME_PATTERN))
                .deliveryTime(LocalDateTimeUtil.parse(evaluationSubDTO.getDeliveryGoodsTime(), DateConstant.DEFAULT_DATE_TIME_PATTERN))
                .phone(evaluationSubDTO.getConsigneePhoneNum())
                .courierNumber(evaluationSubDTO.getCourierNumber())
                .expressCompany(realTimeDTO.getCom())
                .consigneeAddress(evaluationSubDTO.getConsigneeAddress())
                .consigneeName(evaluationSubDTO.getConsigneeName())
                .dynamicContext(realTimeDTO.getLogisticsDynamicList() == null ? null : JSONObject.toJSONString(realTimeDTO.getLogisticsDynamicList()))
                .status(realTimeDTO.getState())
                .businessStatus("已完成".equals(evaluationSubDTO.getOrderStatus()) ? (short) 1 : (short) 0)
                .build());
    }

    @EventListener
    @Transactional(rollbackFor = Exception.class)
    public void syncRealTimeLogistics(SyncLogisticsEvent event) {
        Object object = event.getObject();
        if (!(object instanceof LogisticsInfo)) {
            return;
        }
        LogisticsInfo logisticsInfo = (LogisticsInfo) object;
        ExpressCompany expressCompany = ExpressCompany.getByCode(logisticsInfo.getExpressCompany());
        LogisticsRealTimeDTO realTimeDTO = expressServiceApi.realTimeLogistics(expressCompany, logisticsInfo.getCourierNumber(), logisticsInfo.getPhone());
        logisticsInfo.setStatus(realTimeDTO.getState());
        logisticsInfo.setExpressCompany(realTimeDTO.getCom());
        logisticsInfo.setDynamicContext(realTimeDTO.getLogisticsDynamicList() == null ? null : JSONObject.toJSONString(realTimeDTO.getLogisticsDynamicList()));
        if (logisticsInfo.isSing() && logisticsInfo.getModule().equals(LogisticsModule.SAMPLES.getModuleCode())) {
            // 样品已签收数据需要更改业务状态为已完成
            LogisticsModuleService service = logisticsModlueHandler.getService(logisticsInfo.getModule());
            service.businessStatusFinish(logisticsInfo.getModuleId());
        }
        logisticsInfoService.updateById(logisticsInfo);
    }
}
